import React, { useState, useEffect } from 'react';
import { connect } from 'umi';
import { Button, Upload, Modal, message } from 'antd';
import { TRMessage } from '#/components';
import {
  DownloadOutlined,
  CheckCircleOutlined,
  ExclamationCircleOutlined,
} from '#/utils/antdIcons';
import { useTRState } from '#/utils/trHooks';
import { TJModel } from '@/pages/ETrade/components';
import { importConfig } from '../../constant';

import _ from 'lodash';
import { getTemplate } from '../../services';
import moment from 'moment';
import styles from './index.less';

const { Dragger } = Upload;

const sheetToJson = (result) => {
  const workbook = XLSX.read(new Uint8Array(result), { type: 'array', cellDates: true });
  const firstSheetName = workbook.SheetNames[0];
  // 只针对该页面取第一个名称
  const worksheet = workbook.Sheets[firstSheetName];
  const list = XLSX.utils.sheet_to_json(worksheet, {
    defval: '',
    dataNF: 'YYYY-MM-DD',
  });
  const currentName = Object.keys(list[0])[0] || '';
  return {
    list,
    name: currentName,
  };
};

const verifyFile = (list, name, isSd) => {
  const importMapping = importConfig(isSd);
  let errMsgs = [];
  let body = list.slice(3);
  if (body.length !== 24 && !isSd) {
    errMsgs.push(`导入的${isSd ? '日期' : '时点'}数据只能为1-24`);
  }

  if (body.length > 0 && errMsgs.length === 0) {
    for (let i = 0; i < body.length; i++) {
      let row = body[i];
      let rowStr = [];
      for (let k in row) {
        if (isSd && k === name && row[name]) {
          const date = moment(row[name], moment.ISO_8601, true).isValid();
          if (!date) {
            rowStr.push('日期格式不正确');
          }
        }

        if (importMapping[k]) {
          if (_.isFunction(importMapping[k].rule)) {
            const err = importMapping[k].rule(row[k], row);
            if (err) {
              rowStr.push(err);
            }
          }
        }
      }
      if (rowStr.length > 0) {
        let str = `第${i + 6}行：${rowStr.join(',')}`;
        errMsgs.push(str);
      }
    }
  }

  return errMsgs;
};

const ImportBtn = (props) => {
  const { disabled, formData, tradeSeqId } = props;
  const [fileError, setFileError] = useState(null);
  const [fileInfo, setFileInfo] = useState(null);
  const [isShowMore, setIsShowMore] = useState(false);
  const [uploadDate, setUploadDate] = useState('');

  const [state, setState] = useTRState({
    finalyFile: [], // 最终保存文件
    saveType: 0, // 确认按钮状态
    visible: false, // 导入弹窗展示
    btnLoding: false, // 弹窗确认按钮loding
  });

  const draggerProps = {
    name: 'file',
    multiple: false,
    showUploadList: false,
    accept: '.xls, .xlsx',
    maxCount: 1,
  };

  useEffect(() => {
    const formatDate = () => {
      return new Date().toLocaleString();
    };

    setUploadDate(formatDate());
  }, [state.finalyFile]);

  const _beforeUpload = (file) => {
    if (!file.uid) {
      file.uid = Date.now();
    }
    if (!file.status) {
      file.status = 'done';
    }
    // 通过FileReader对象读取文件
    const fileReader = new FileReader();
    fileReader.onload = async (event) => {
      const { result } = event.target;
      const { list, name } = sheetToJson(result);
      // const str = props.isSd ? '集中竞价申报导入模板(山东)' : '集中竞价申报导入模板(山西)';

      if (name.indexOf('集中竞价') < 0) {
        setFileError(['请上传正确模板!']);
        if (file.status) {
          file.status = 'error';
        }
        setFileInfo(file);
        return false;
      }

      const errMsgs = verifyFile(list, name, props.isSd);

      if (errMsgs.length > 0) {
        setFileError(errMsgs);
        file.status = 'error';
        setFileInfo(file);
        return false;
      }

      setFileInfo(file);
      setState({
        saveType: 1,
        finalyFile: file,
      });
    };

    fileReader.readAsArrayBuffer(file);

    return false;
  };

  const downFile = () => {
    getTemplate(formData.marketId, tradeSeqId)
      .then((response) => {
        if (response && !response.statusCode) {
          const url = window.URL.createObjectURL(new Blob([response]));
          const link = document.createElement('a');
          link.href = url;
          link.setAttribute('download', '集中竞价申报导入模板.xlsx');
          document.body.appendChild(link);
          link.click();
          link.remove();
        } else {
          if (response && response.statusCode && response.statusCode !== '1000') {
            message.error(response.message);
          }
        }
      })
      .catch((error) => {
        TRMessage.error('模板下载失败！');
      });
  };

  const onImport = () => {
    // 导入数据
    if (disabled) return TRMessage.info('请联系管理员获取相关权限');
    setState({
      visible: true,
    });
  };

  const onClose = () => {
    setFileInfo(null);
    setFileError(null);
    setState({
      visible: false,
      saveType: 0,
    });
  };

  const convertImportData = (arr, name) => {
    const importMapping = importConfig(props.isSd);
    const obj = {
      // 列表数据
      tableData: [],
      // 交易单元
      marketingUnit: [],
    };

    let header = arr.slice(0, 3);
    let body = arr.slice(3);

    if (header.length > 0) {
      const first = header[0];
      if (first.__EMPTY && first.__EMPTY !== '-') {
        const arr = first.__EMPTY.split('、');
        if (arr && arr.length > 0 && props.stations) {
          arr.forEach((v) => {
            const item = _.find(props.stations, (n) => n.title.indexOf(v) > -1);
            if (item) {
              obj.marketingUnit.push(item.value);
            }
          });
        }
      }
    }

    body.forEach((row, index) => {
      let rowData = {};

      for (let i in row) {
        if (importMapping[i] && importMapping[i].key) {
          if (importMapping[i].translate) {
            const translate = importMapping[i].translate;
            for (let r in translate) {
              if (row[i].indexOf(r) > -1) {
                rowData[importMapping[i].key] = translate[r];
              }
            }
          }
          if (_.isFunction(importMapping[i].fn)) {
            const data = importMapping[i].fn(row, i);
            rowData = { ...rowData, ...data };
          }
          if (!importMapping[i].fn && !importMapping[i].translate) {
            rowData[importMapping[i].key] = Number(row[i]);
          }
        }
      }
      if (props.isSd) {
        if (row[name]) {
          if (moment.isDate(row[name])) {
            rowData.hourOrder = moment(row[name]).add(1, 'days').format('YYYY-MM-DD');
          } else {
            rowData.hourOrder = row[name];
          }
        }
      } else {
        rowData.hourOrder = index + 1;
      }
      obj.tableData.push(rowData);
    });

    return obj;
  };

  const importHanldr = () => {
    if (btnLoding) return;
    setState({
      btnLoding: true,
    });
    const fileReader = new FileReader();
    fileReader.readAsArrayBuffer(state.finalyFile);
    fileReader.onload = (event) => {
      const { result } = event.target;
      const { list, name } = sheetToJson(result);
      const obj = convertImportData(list, name);

      if (props.currentProgramId) {
        if (props.currentProgramId === '-1') {
          props.dispatch({
            type: 'tenDaysCentralizedBidding/editProgramInfoEffect',
            payload: {
              deletePermission: true,
              editPermission: true,
              programInfo: {
                adjust: true,
              },
              hourOrderInfoList: obj.tableData,
            },
          });

          props.dispatch({
            type: 'tenDaysCentralizedBidding/setSelectedUnitIds',
            payload: obj.marketingUnit,
          });

          TRMessage.success('导入成功');
        } else {
          props.addProgramAndSetListData && props.addProgramAndSetListData(obj);
        }
      }

      onClose();
      setState({
        btnLoding: false,
      });
    };
  };

  const formatSize = (size) => {
    if (size < 1024) return `${size} B`;
    if (size < 1024 * 1024) return `${(size / 1024).toFixed(2)} KB`;
    return `${(size / (1024 * 1024)).toFixed(2)} MB`;
  };

  const handleDelete = () => {
    setFileInfo(null);
    setFileError(null);
    setState({ saveType: 0 });
  };

  const { visible, btnLoding, saveType } = state;
  return (
    <>
      <Button
        style={{ padding: 0 }}
        className={`${disabled && styles.disabled}`}
        type="link"
        icon={<DownloadOutlined />}
        onClick={onImport}
      >
        导入
      </Button>
      <TJModel
        title={'导入'}
        width={530}
        visible={visible}
        onCancel={onClose}
        footer={[
          <Button key="back" onClick={onClose}>
            取消
          </Button>,
          !!saveType && (
            <Button key="submit" type="primary" loading={btnLoding} onClick={importHanldr}>
              提交
            </Button>
          ),
        ]}
      >
        <div className={styles.content}>
          <div className={styles.label}>
            导入文件
            <span className={styles.after}>仅支持Excel文件</span>
          </div>
          <div className={styles.label}>
            下载模板
            <span className={styles.down} onClick={downFile}>
              集中竞价申报导入模板.xlsx
            </span>
          </div>
          <div style={{ display: 'flex', justifyContent: 'center', flexDirection: 'column' }}>
            {!fileInfo ? (
              <div
                style={{
                  width: '481px',
                  height: '160px',
                }}
              >
                <Dragger {...draggerProps} beforeUpload={_beforeUpload}>
                  <p className={styles.label}>
                    <span className={styles.down}>点击上传</span>
                    <span className={styles.after_text}>/ 拖拽到此区域</span>
                  </p>
                </Dragger>
              </div>
            ) : (
              <>
                <div
                  className={styles.file_box}
                  style={
                    fileInfo?.status === 'done' && !fileError
                      ? { border: '1px dashed #434343' }
                      : { border: '1px dashed #c12929' }
                  }
                >
                  <div className={styles.file_info}>
                    <p className={styles.label}>
                      {fileInfo?.name}{' '}
                      {fileInfo?.status === 'done' && !fileError ? (
                        <CheckCircleOutlined style={{ color: 'green', marginLeft: '10px' }} />
                      ) : (
                        <ExclamationCircleOutlined style={{ color: 'red', marginLeft: '10px' }} />
                      )}
                    </p>
                    <p className={styles.after_text}>文件大小:{formatSize(fileInfo?.size)}</p>
                    <p className={styles.after_text}>上传日期: {uploadDate}</p>
                    <div style={{ paddingTop: '13px' }}>
                      <span className={styles.file_footer} onClick={handleDelete}>
                        删除
                      </span>
                    </div>
                  </div>
                </div>
                {fileError && (
                  <div style={{ color: '#c12929', marginTop: '4px' }}>
                    {JSON.stringify(fileError)?.slice(1, -2).substring(1, 20)}
                    {JSON.stringify(fileError).slice(1, -2)?.length > 20 && (
                      <>
                        ......
                        <span className={styles.more} onClick={() => setIsShowMore(true)}>
                          更多
                        </span>
                      </>
                    )}
                  </div>
                )}
                <Modal
                  width={720}
                  className={styles.modal}
                  centered={true}
                  visible={isShowMore}
                  onOk={() => {
                    setIsShowMore(false);
                  }}
                  onCancel={() => {
                    setIsShowMore(false);
                  }}
                  maskClosable={true}
                  title={
                    <div key="title" className={styles.modal_title}>
                      文件上传错误内容查看
                    </div>
                  }
                >
                  {fileError &&
                    fileError.length > 0 &&
                    fileError.map((v, i) => {
                      // 不会出现元素变动情况直接用索引没问题
                      return <div key={i}>{v};</div>;
                    })}
                </Modal>
              </>
            )}
          </div>
        </div>
      </TJModel>
    </>
  );
};

export default connect(({ tenDaysCentralizedBidding }) => ({
  currentProgramInfo: tenDaysCentralizedBidding.currentProgramInfo,
  selectedRowKeys: tenDaysCentralizedBidding.selectedRowKeys,
  selectedUnitIds: tenDaysCentralizedBidding.selectedUnitIds,
  stations: tenDaysCentralizedBidding.stations,
  formData: tenDaysCentralizedBidding.formData,
  tradeSeqId: tenDaysCentralizedBidding.tradeSeqId,
  maxValue: tenDaysCentralizedBidding.maxValue,
}))(ImportBtn);
